package com.oauth.server.extend.provider;

import com.oauth.server.extend.authentication.SmsCodeAuthenticationToken;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper;
import org.springframework.security.core.authority.mapping.NullAuthoritiesMapper;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.util.StringUtils;

/**
 * @作者: 林江
 * @创建时间: 2024/1/13
 * @功能:
 */
public class SmsCodeAuthenticationProvider implements AuthenticationProvider {

    private UserDetailsService userDetailsService;

    private GrantedAuthoritiesMapper authoritiesMapper = new NullAuthoritiesMapper();

    public void setUserDetailsService(UserDetailsService userDetailsService) {
        this.userDetailsService = userDetailsService;
    }

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        // 校验验证码
//        check(authentication);
        String phone = determineUsername(authentication);
        // 查询数据库
        UserDetails user = this.userDetailsService.loadUserByUsername(phone);
        return createSuccessAuthentication(phone, authentication, user);
    }

    /**
     * 校验验证码
     *
     * @param authentication
     */
    private void check(Authentication authentication) {
        Object credentials = authentication.getCredentials();
        if (credentials == null) {
            throw new BadCredentialsException("验证码不存在");
        }

        String smsCode = credentials.toString();
        // TODO redis服务，因为要从redis中获取验证码。
        String redisSmsCode = null;
        if (StringUtils.isEmpty(redisSmsCode)) {
            throw new BadCredentialsException("验证码不存在");
        } else if (smsCode.equals(smsCode)) {
            throw new BadCredentialsException("验证码错误");
        }
    }

    /**
     * 抽取phone
     *
     * @param authentication
     * @return
     */
    private String determineUsername(Authentication authentication) {
        return (authentication.getPrincipal() == null) ? "NONE_PROVIDED" : authentication.getName();
    }

    protected Authentication createSuccessAuthentication(Object principal, Authentication authentication, UserDetails user) {
        SmsCodeAuthenticationToken result = new SmsCodeAuthenticationToken(principal, authentication.getCredentials(), this.authoritiesMapper.mapAuthorities(user.getAuthorities()));
        result.setDetails(authentication.getDetails());
        return result;
    }

    /**
     * 判断传入的authentication是否符合要求
     *
     * @param authentication
     * @return
     */
    @Override
    public boolean supports(Class<?> authentication) {
        return (SmsCodeAuthenticationToken.class.isAssignableFrom(authentication));
    }

}
